package com.zhu.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.zhu.exception.SecurityException;
import com.zhu.pojo.User;
import com.zhu.result.RespBeanEnum;
import com.zhu.service.IRoleService;
import com.zhu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    @Qualifier("myRedisTemplate")
    private RedisTemplate redisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userService.userByName(username);
        if(user==null){
            throw new UsernameNotFoundException(RespBeanEnum.USERNAME_PASSWORD.getMsg());
        }
;
        return new UserDetail(user.getUid(),user.getUsername(),user.getPassword(),getUserAuthorities(username,user.getRoleId()));
    }

    /*
        通过传递过来的userId去查询对应的用户权限
     */
    public List<GrantedAuthority> getUserAuthorities(String username,Long roleId) {
        List<GrantedAuthority> authorityList = null;
        JSON.parseObject((String) redisTemplate.opsForValue().get("perms:" + username),new TypeReference<List<GrantedAuthority>>(){}) ;
        if(authorityList!=null){
            return authorityList;
        }
        //首先获取到用户的权限字符为字符串
        String perms = roleService.getPerms(roleId);
        //将权限字符进行转换，并且去掉左右两边的中括号
        String authority = JSONArray.parseArray(perms, String.class).toString().replace("[", "").replace("]", "");
        //利用AuthorityUtils工具类中的方法将String字符串转换成List<GrantedAuthority>使得程序想要的
        authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList(authority);
        //将权限存储到Redis当中
        redisTemplate.opsForValue().set("perms:"+username, JSON.toJSONString(authorityList));
        //将转换后的权限直接返回出去即可
        return authorityList;
    }

}
